/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.bff.slimserver.musicjukebox.ui.components;

import com.bff.bjj.ui.component.BJJList;
import com.bff.slimserver.music.MusicObjects;
import com.bff.slimserver.music.exceptions.PlaylistException;
import com.bff.slimserver.musicjukebox.lib.JukeboxProperties;
import com.bff.slimserver.musicjukebox.lib.actions.PlaylistAddArtistAction;
import com.bff.slimserver.musicjukebox.lib.actions.PlaylistInsertArtistAction;
import com.bff.slimserver.musicjukebox.lib.actions.PlaylistLoadArtistAction;
import com.bff.slimserver.musicjukebox.lib.actions.ViewArtistAction;
import com.bff.slimserver.musicjukebox.ui.ArtistDialog;
import com.bff.bjj.utils.Utils;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.DefaultListModel;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import org.bff.slimserver.SlimDatabase;
import org.bff.slimserver.SlimPlaylist;
import org.bff.slimserver.exception.SlimConnectionException;
import org.bff.slimserver.musicobjects.SlimArtist;
import org.bff.slimserver.musicobjects.SlimContributor;

/**
 *
 * @author Bill
 */
public class ArtistList extends BJJList implements MouseListener {

    private SlimDatabase database;
    private DefaultListModel artistListModel;
    private JPopupMenu artistMenu;
    private SlimPlaylist playlist;
    private List<SlimContributor> contributors;
    private List<SlimArtist> artists;
    private boolean showArtistonDoubleClick;
    
    public ArtistList() {
        super();
        contributors = new ArrayList<SlimContributor>();
        artists = new ArrayList<SlimArtist>();

        try {
            setDatabase(JukeboxProperties.getInstance().getDatabase());
            setPlaylist(JukeboxProperties.getInstance().getPlaylist());
        } catch (SlimConnectionException ex) {
            Logger.getLogger(ArtistList.class.getName()).log(Level.SEVERE, null, ex);
        } catch (PlaylistException ex) {
            Logger.getLogger(ArtistList.class.getName()).log(Level.SEVERE, null, ex);
        }
        setCellRenderer(new ArtistListCellRenderer());
        addMouseListener(this);       

        this.showArtistonDoubleClick = true;
    }

    public ArtistList(Collection<SlimArtist> artists) {
        this();
        listArtists(artists);
    }

    public void setArtist(Collection<SlimArtist> artists) {
        listArtists(artists);
    }

    public void setContributors(Collection<SlimContributor> contributors) {
        this.contributors = new ArrayList<SlimContributor>(contributors);
        loadList();
    }

    private void listArtists(Collection<SlimArtist> artists) {
        this.artists = new ArrayList<SlimArtist>(artists);
        loadList();
    }

    public void listAll() {
        listArtists(MusicObjects.getArtists());
    }

    public void filterList(String filter) {
        if ("".equals(filter.trim())) {
            listAll();
        } else {
            try {
                artistListModel.clear();

                for (SlimArtist artist : artists) {
                    if (artist.getName().toLowerCase().startsWith(filter.toLowerCase())) {
                        artistListModel.addElement(artist);
                    }

                }

                for (SlimContributor contributor : contributors) {
                    if (contributor.getName().toLowerCase().startsWith(filter.toLowerCase())) {
                        artistListModel.addElement(contributor);
                    }
                }

                setSelectedIndex(0);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public void clearFilter() {
        loadList();
    }

    public SlimArtist getSelectedArtist() {
        if (getSelectedValue() == null) {
            return null;
        }

        return (SlimArtist) getSelectedValue();
    }

    public SlimDatabase getDatabase() {
        return database;
    }

    private void setDatabase(SlimDatabase database) {
        this.database = database;
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        if (e.getClickCount() == 2) {
            if (isShowArtistonDoubleClick()) {
                SlimArtist artist = getSelectedArtist();
                ArtistDialog artistDialog = new ArtistDialog(Utils.getParentComponent(this), artist);
                artistDialog.setVisible(true);
            }
        } else {
            createArtistPlayPopUp(e);
        }
    }

    @Override
    public void mousePressed(MouseEvent e) {
        createArtistPlayPopUp(e);
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        createArtistPlayPopUp(e);
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        //throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void mouseExited(MouseEvent e) {
        //throw new UnsupportedOperationException("Not supported yet.");
    }

    private void createArtistPlayPopUp(MouseEvent e) {
        if (e.isPopupTrigger()) {
            setSelectedIndex(locationToIndex(e.getPoint()));
            SlimArtist artist = getSelectedArtist();
            artistMenu = new JPopupMenu();
            artistMenu.add(new JMenuItem(new PlaylistAddArtistAction(getPlaylist(), artist)));
            artistMenu.add(new JMenuItem(new PlaylistInsertArtistAction(getPlaylist(), artist)));
            artistMenu.add(new JMenuItem(new PlaylistLoadArtistAction(getPlaylist(), artist)));
            artistMenu.add(new JMenuItem(new ViewArtistAction(Utils.getParentComponent(this), artist)));
            artistMenu.setVisible(true);
            artistMenu.show(e.getComponent(), e.getX(), e.getY());
        }
    }

    public SlimPlaylist getPlaylist() {
        return playlist;
    }

    private void setPlaylist(SlimPlaylist playlist) {
        this.playlist = playlist;
    }

    private void loadList() {
        artistListModel = new DefaultListModel();
        try {
            for (SlimArtist artist : artists) {
                artistListModel.addElement(artist);
            }

            for (SlimContributor contributor : contributors) {
                artistListModel.addElement(contributor);
            }

            setModel(artistListModel);
            setSelectedIndex(0);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @return the showArtistonDoubleClick
     */
    public boolean isShowArtistonDoubleClick() {
        return showArtistonDoubleClick;
    }

    /**
     * @param showArtistonDoubleClick the showArtistonDoubleClick to set
     */
    public void setShowArtistonDoubleClick(boolean showArtistonDoubleClick) {
        this.showArtistonDoubleClick = showArtistonDoubleClick;
    }

    @Override
    public void positionForKey(String keyTyped) {
        for (int k = 0; k < artistListModel.getSize(); k++) {
            SlimArtist artist = ((SlimArtist) artistListModel.getElementAt(k));
            if (artist.getName().toLowerCase().startsWith(keyTyped)) {
                setSelectedIndex(k);
                ensureIndexIsVisible(k);
                break;
            }
        }
    }

    @Override
    public void positionForCode(int keyCode) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}
